home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / httplib.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  35KB  |  1,228 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''HTTP/1.1 client library
  5.  
  6. <intro stuff goes here>
  7. <other stuff, too>
  8.  
  9. HTTPConnection goes through a number of "states", which define when a client
  10. may legally make another request or fetch the response for a particular
  11. request. This diagram details these state transitions:
  12.  
  13.     (null)
  14.       |
  15.       | HTTPConnection()
  16.       v
  17.     Idle
  18.       |
  19.       | putrequest()
  20.       v
  21.     Request-started
  22.       |
  23.       | ( putheader() )*  endheaders()
  24.       v
  25.     Request-sent
  26.       |
  27.       | response = getresponse()
  28.       v
  29.     Unread-response   [Response-headers-read]
  30.       |\\____________________
  31.       |                     |
  32.       | response.read()     | putrequest()
  33.       v                     v
  34.     Idle                  Req-started-unread-response
  35.                      ______/|
  36.                    /        |
  37.    response.read() |        | ( putheader() )*  endheaders()
  38.                    v        v
  39.        Request-started    Req-sent-unread-response
  40.                             |
  41.                             | response.read()
  42.                             v
  43.                           Request-sent
  44.  
  45. This diagram presents the following rules:
  46.   -- a second request may not be started until {response-headers-read}
  47.   -- a response [object] cannot be retrieved until {request-sent}
  48.   -- there is no differentiation between an unread response body and a
  49.      partially read response body
  50.  
  51. Note: this enforcement is applied by the HTTPConnection class. The
  52.       HTTPResponse class does not enforce this state machine, which
  53.       implies sophisticated clients may accelerate the request/response
  54.       pipeline. Caution should be taken, though: accelerating the states
  55.       beyond the above pattern may imply knowledge of the server\'s
  56.       connection-close behavior for certain requests. For example, it
  57.       is impossible to tell whether the server will close the connection
  58.       UNTIL the response headers have been read; this means that further
  59.       requests cannot be placed into the pipeline until it is known that
  60.       the server will NOT be closing the connection.
  61.  
  62. Logical State                  __state            __response
  63. -------------                  -------            ----------
  64. Idle                           _CS_IDLE           None
  65. Request-started                _CS_REQ_STARTED    None
  66. Request-sent                   _CS_REQ_SENT       None
  67. Unread-response                _CS_IDLE           <response_class>
  68. Req-started-unread-response    _CS_REQ_STARTED    <response_class>
  69. Req-sent-unread-response       _CS_REQ_SENT       <response_class>
  70. '''
  71. from array import array
  72. import socket
  73. from sys import py3kwarning
  74. from urlparse import urlsplit
  75. import warnings
  76. warnings.catch_warnings().__enter__()
  77.  
  78. try:
  79.     import mimetools
  80. finally:
  81.     pass
  82.  
  83.  
  84. try:
  85.     from cStringIO import StringIO
  86. except ImportError:
  87.     warnings.catch_warnings().__exit__
  88.     warnings.catch_warnings().__exit__
  89.     warnings.catch_warnings()
  90.     from StringIO import StringIO
  91. except:
  92.     warnings.catch_warnings().__exit__
  93.  
  94. __all__ = [
  95.     'HTTP',
  96.     'HTTPResponse',
  97.     'HTTPConnection',
  98.     'HTTPException',
  99.     'NotConnected',
  100.     'UnknownProtocol',
  101.     'UnknownTransferEncoding',
  102.     'UnimplementedFileMode',
  103.     'IncompleteRead',
  104.     'InvalidURL',
  105.     'ImproperConnectionState',
  106.     'CannotSendRequest',
  107.     'CannotSendHeader',
  108.     'ResponseNotReady',
  109.     'BadStatusLine',
  110.     'error',
  111.     'responses']
  112. HTTP_PORT = 80
  113. HTTPS_PORT = 443
  114. _UNKNOWN = 'UNKNOWN'
  115. _CS_IDLE = 'Idle'
  116. _CS_REQ_STARTED = 'Request-started'
  117. _CS_REQ_SENT = 'Request-sent'
  118. CONTINUE = 100
  119. SWITCHING_PROTOCOLS = 101
  120. PROCESSING = 102
  121. OK = 200
  122. CREATED = 201
  123. ACCEPTED = 202
  124. NON_AUTHORITATIVE_INFORMATION = 203
  125. NO_CONTENT = 204
  126. RESET_CONTENT = 205
  127. PARTIAL_CONTENT = 206
  128. MULTI_STATUS = 207
  129. IM_USED = 226
  130. MULTIPLE_CHOICES = 300
  131. MOVED_PERMANENTLY = 301
  132. FOUND = 302
  133. SEE_OTHER = 303
  134. NOT_MODIFIED = 304
  135. USE_PROXY = 305
  136. TEMPORARY_REDIRECT = 307
  137. BAD_REQUEST = 400
  138. UNAUTHORIZED = 401
  139. PAYMENT_REQUIRED = 402
  140. FORBIDDEN = 403
  141. NOT_FOUND = 404
  142. METHOD_NOT_ALLOWED = 405
  143. NOT_ACCEPTABLE = 406
  144. PROXY_AUTHENTICATION_REQUIRED = 407
  145. REQUEST_TIMEOUT = 408
  146. CONFLICT = 409
  147. GONE = 410
  148. LENGTH_REQUIRED = 411
  149. PRECONDITION_FAILED = 412
  150. REQUEST_ENTITY_TOO_LARGE = 413
  151. REQUEST_URI_TOO_LONG = 414
  152. UNSUPPORTED_MEDIA_TYPE = 415
  153. REQUESTED_RANGE_NOT_SATISFIABLE = 416
  154. EXPECTATION_FAILED = 417
  155. UNPROCESSABLE_ENTITY = 422
  156. LOCKED = 423
  157. FAILED_DEPENDENCY = 424
  158. UPGRADE_REQUIRED = 426
  159. INTERNAL_SERVER_ERROR = 500
  160. NOT_IMPLEMENTED = 501
  161. BAD_GATEWAY = 502
  162. SERVICE_UNAVAILABLE = 503
  163. GATEWAY_TIMEOUT = 504
  164. HTTP_VERSION_NOT_SUPPORTED = 505
  165. INSUFFICIENT_STORAGE = 507
  166. NOT_EXTENDED = 510
  167. responses = {
  168.     100: 'Continue',
  169.     101: 'Switching Protocols',
  170.     200: 'OK',
  171.     201: 'Created',
  172.     202: 'Accepted',
  173.     203: 'Non-Authoritative Information',
  174.     204: 'No Content',
  175.     205: 'Reset Content',
  176.     206: 'Partial Content',
  177.     300: 'Multiple Choices',
  178.     301: 'Moved Permanently',
  179.     302: 'Found',
  180.     303: 'See Other',
  181.     304: 'Not Modified',
  182.     305: 'Use Proxy',
  183.     306: '(Unused)',
  184.     307: 'Temporary Redirect',
  185.     400: 'Bad Request',
  186.     401: 'Unauthorized',
  187.     402: 'Payment Required',
  188.     403: 'Forbidden',
  189.     404: 'Not Found',
  190.     405: 'Method Not Allowed',
  191.     406: 'Not Acceptable',
  192.     407: 'Proxy Authentication Required',
  193.     408: 'Request Timeout',
  194.     409: 'Conflict',
  195.     410: 'Gone',
  196.     411: 'Length Required',
  197.     412: 'Precondition Failed',
  198.     413: 'Request Entity Too Large',
  199.     414: 'Request-URI Too Long',
  200.     415: 'Unsupported Media Type',
  201.     416: 'Requested Range Not Satisfiable',
  202.     417: 'Expectation Failed',
  203.     500: 'Internal Server Error',
  204.     501: 'Not Implemented',
  205.     502: 'Bad Gateway',
  206.     503: 'Service Unavailable',
  207.     504: 'Gateway Timeout',
  208.     505: 'HTTP Version Not Supported' }
  209. MAXAMOUNT = 1048576
  210.  
  211. class HTTPMessage(mimetools.Message):
  212.     
  213.     def addheader(self, key, value):
  214.         '''Add header for field key handling repeats.'''
  215.         prev = self.dict.get(key)
  216.         if prev is None:
  217.             self.dict[key] = value
  218.         else:
  219.             combined = ', '.join((prev, value))
  220.             self.dict[key] = combined
  221.  
  222.     
  223.     def addcontinue(self, key, more):
  224.         '''Add more field data from a continuation line.'''
  225.         prev = self.dict[key]
  226.         self.dict[key] = prev + '\n ' + more
  227.  
  228.     
  229.     def readheaders(self):
  230.         '''Read header lines.
  231.  
  232.         Read header lines up to the entirely blank line that terminates them.
  233.         The (normally blank) line that ends the headers is skipped, but not
  234.         included in the returned list.  If a non-header line ends the headers,
  235.         (which is an error), an attempt is made to backspace over it; it is
  236.         never included in the returned list.
  237.  
  238.         The variable self.status is set to the empty string if all went well,
  239.         otherwise it is an error message.  The variable self.headers is a
  240.         completely uninterpreted list of lines contained in the header (so
  241.         printing them will reproduce the header exactly as it appears in the
  242.         file).
  243.  
  244.         If multiple header fields with the same name occur, they are combined
  245.         according to the rules in RFC 2616 sec 4.2:
  246.  
  247.         Appending each subsequent field-value to the first, each separated
  248.         by a comma. The order in which header fields with the same field-name
  249.         are received is significant to the interpretation of the combined
  250.         field value.
  251.         '''
  252.         self.dict = { }
  253.         self.unixfrom = ''
  254.         self.headers = hlist = []
  255.         self.status = ''
  256.         headerseen = ''
  257.         firstline = 1
  258.         startofline = None
  259.         unread = None
  260.         tell = None
  261.         if hasattr(self.fp, 'unread'):
  262.             unread = self.fp.unread
  263.         elif self.seekable:
  264.             tell = self.fp.tell
  265.         
  266.         while True:
  267.             if tell:
  268.                 
  269.                 try:
  270.                     startofline = tell()
  271.                 except IOError:
  272.                     startofline = None
  273.                     tell = None
  274.                     self.seekable = 0
  275.                 except:
  276.                     None<EXCEPTION MATCH>IOError
  277.                 
  278.  
  279.             None<EXCEPTION MATCH>IOError
  280.             line = self.fp.readline()
  281.             if not line:
  282.                 self.status = 'EOF in headers'
  283.                 break
  284.             
  285.             if firstline and line.startswith('From '):
  286.                 self.unixfrom = self.unixfrom + line
  287.                 continue
  288.             
  289.             firstline = 0
  290.             if headerseen and line[0] in ' \t':
  291.                 hlist.append(line)
  292.                 self.addcontinue(headerseen, line.strip())
  293.                 continue
  294.             elif self.iscomment(line):
  295.                 continue
  296.             elif self.islast(line):
  297.                 break
  298.             
  299.             headerseen = self.isheader(line)
  300.             if headerseen:
  301.                 hlist.append(line)
  302.                 self.addheader(headerseen, line[len(headerseen) + 1:].strip())
  303.                 continue
  304.                 continue
  305.             if not self.dict:
  306.                 self.status = 'No headers'
  307.             else:
  308.                 self.status = 'Non-header line where header expected'
  309.             if unread:
  310.                 unread(line)
  311.             elif tell:
  312.                 self.fp.seek(startofline)
  313.             else:
  314.                 self.status = self.status + '; bad seek'
  315.             break
  316.  
  317.  
  318.  
  319. class HTTPResponse:
  320.     
  321.     def __init__(self, sock, debuglevel = 0, strict = 0, method = None):
  322.         self.fp = sock.makefile('rb', 0)
  323.         self.debuglevel = debuglevel
  324.         self.strict = strict
  325.         self._method = method
  326.         self.msg = None
  327.         self.version = _UNKNOWN
  328.         self.status = _UNKNOWN
  329.         self.reason = _UNKNOWN
  330.         self.chunked = _UNKNOWN
  331.         self.chunk_left = _UNKNOWN
  332.         self.length = _UNKNOWN
  333.         self.will_close = _UNKNOWN
  334.  
  335.     
  336.     def _read_status(self):
  337.         line = self.fp.readline()
  338.         if self.debuglevel > 0:
  339.             print 'reply:', repr(line)
  340.         
  341.         if not line:
  342.             raise BadStatusLine(line)
  343.         line
  344.         
  345.         try:
  346.             (version, status, reason) = line.split(None, 2)
  347.         except ValueError:
  348.             
  349.             try:
  350.                 (version, status) = line.split(None, 1)
  351.                 reason = ''
  352.             except ValueError:
  353.                 version = ''
  354.             except:
  355.                 None<EXCEPTION MATCH>ValueError
  356.             
  357.  
  358.             None<EXCEPTION MATCH>ValueError
  359.  
  360.         if not version.startswith('HTTP/'):
  361.             if self.strict:
  362.                 self.close()
  363.                 raise BadStatusLine(line)
  364.             self.strict
  365.             self.fp = LineAndFileWrapper(line, self.fp)
  366.             return ('HTTP/0.9', 200, '')
  367.         version.startswith('HTTP/')
  368.         
  369.         try:
  370.             status = int(status)
  371.             if status < 100 or status > 999:
  372.                 raise BadStatusLine(line)
  373.             status > 999
  374.         except ValueError:
  375.             raise BadStatusLine(line)
  376.  
  377.         return (version, status, reason)
  378.  
  379.     
  380.     def begin(self):
  381.         if self.msg is not None:
  382.             return None
  383.         while True:
  384.             (version, status, reason) = self._read_status()
  385.             if status != CONTINUE:
  386.                 break
  387.             
  388.             while True:
  389.                 skip = self.fp.readline().strip()
  390.                 if not skip:
  391.                     break
  392.                 
  393.                 if self.debuglevel > 0:
  394.                     print 'header:', skip
  395.                     continue
  396.         self.status = status
  397.         self.reason = reason.strip()
  398.         if version == 'HTTP/1.0':
  399.             self.version = 10
  400.         elif version.startswith('HTTP/1.'):
  401.             self.version = 11
  402.         elif version == 'HTTP/0.9':
  403.             self.version = 9
  404.         else:
  405.             raise UnknownProtocol(version)
  406.         if (version == 'HTTP/1.0').version == 9:
  407.             self.length = None
  408.             self.chunked = 0
  409.             self.will_close = 1
  410.             self.msg = HTTPMessage(StringIO())
  411.             return None
  412.         self.msg = HTTPMessage(self.fp, 0)
  413.         if self.debuglevel > 0:
  414.             for hdr in self.msg.headers:
  415.                 print 'header:', hdr,
  416.             
  417.         
  418.         self.msg.fp = None
  419.         tr_enc = self.msg.getheader('transfer-encoding')
  420.         if tr_enc and tr_enc.lower() == 'chunked':
  421.             self.chunked = 1
  422.             self.chunk_left = None
  423.         else:
  424.             self.chunked = 0
  425.         self.will_close = self._check_close()
  426.         length = self.msg.getheader('content-length')
  427.         if length and not (self.chunked):
  428.             
  429.             try:
  430.                 self.length = int(length)
  431.             except ValueError:
  432.                 self.length = None
  433.  
  434.             if self.length < 0:
  435.                 self.length = None
  436.             
  437.         else:
  438.             self.length = None
  439.         if not status == NO_CONTENT and status == NOT_MODIFIED:
  440.             if status <= status:
  441.                 pass
  442.             elif status < 200 or self._method == 'HEAD':
  443.                 self.length = 0
  444.             
  445.         if not (self.will_close) and not (self.chunked) and self.length is None:
  446.             self.will_close = 1
  447.         
  448.  
  449.     
  450.     def _check_close(self):
  451.         conn = self.msg.getheader('connection')
  452.         if self.version == 11:
  453.             conn = self.msg.getheader('connection')
  454.             if conn and 'close' in conn.lower():
  455.                 return True
  456.             return False
  457.         if self.msg.getheader('keep-alive'):
  458.             return False
  459.         if conn and 'keep-alive' in conn.lower():
  460.             return False
  461.         pconn = self.msg.getheader('proxy-connection')
  462.         if pconn and 'keep-alive' in pconn.lower():
  463.             return False
  464.         return True
  465.  
  466.     
  467.     def close(self):
  468.         if self.fp:
  469.             self.fp.close()
  470.             self.fp = None
  471.         
  472.  
  473.     
  474.     def isclosed(self):
  475.         return self.fp is None
  476.  
  477.     
  478.     def read(self, amt = None):
  479.         if self.fp is None:
  480.             return ''
  481.         if self.chunked:
  482.             return self._read_chunked(amt)
  483.         if amt is None:
  484.             self.close()
  485.             return s
  486.         s = self.fp.read(amt)
  487.         return s
  488.  
  489.     
  490.     def _read_chunked(self, amt):
  491.         if not self.chunked != _UNKNOWN:
  492.             raise AssertionError
  493.         chunk_left = self.chunk_left
  494.         value = []
  495.         while True:
  496.             if chunk_left is None:
  497.                 line = self.fp.readline()
  498.                 i = line.find(';')
  499.                 if i >= 0:
  500.                     line = line[:i]
  501.                 
  502.                 
  503.                 try:
  504.                     chunk_left = int(line, 16)
  505.                 except ValueError:
  506.                     self.close()
  507.                     raise IncompleteRead(''.join(value))
  508.  
  509.                 if chunk_left == 0:
  510.                     break
  511.                 
  512.             
  513.             if amt is None:
  514.                 value.append(self._safe_read(chunk_left))
  515.             elif amt < chunk_left:
  516.                 value.append(self._safe_read(amt))
  517.                 self.chunk_left = chunk_left - amt
  518.                 return ''.join(value)
  519.             if amt == chunk_left:
  520.                 value.append(self._safe_read(amt))
  521.                 self._safe_read(2)
  522.                 self.chunk_left = None
  523.                 return ''.join(value)
  524.             value.append(self._safe_read(chunk_left))
  525.             amt -= chunk_left
  526.             self._safe_read(2)
  527.             chunk_left = None
  528.             continue
  529.             amt == chunk_left
  530.         while True:
  531.             line = self.fp.readline()
  532.             if not line:
  533.                 break
  534.             
  535.             if line == '\r\n':
  536.                 break
  537.                 continue
  538.         self.close()
  539.         return ''.join(value)
  540.  
  541.     
  542.     def _safe_read(self, amt):
  543.         '''Read the number of bytes requested, compensating for partial reads.
  544.  
  545.         Normally, we have a blocking socket, but a read() can be interrupted
  546.         by a signal (resulting in a partial read).
  547.  
  548.         Note that we cannot distinguish between EOF and an interrupt when zero
  549.         bytes have been read. IncompleteRead() will be raised in this
  550.         situation.
  551.  
  552.         This function should be used when <amt> bytes "should" be present for
  553.         reading. If the bytes are truly not available (due to EOF), then the
  554.         IncompleteRead exception can be used to detect the problem.
  555.         '''
  556.         s = []
  557.         while amt > 0:
  558.             chunk = self.fp.read(min(amt, MAXAMOUNT))
  559.             if not chunk:
  560.                 raise IncompleteRead(''.join(s), amt)
  561.             chunk
  562.             s.append(chunk)
  563.             amt -= len(chunk)
  564.         return ''.join(s)
  565.  
  566.     
  567.     def getheader(self, name, default = None):
  568.         if self.msg is None:
  569.             raise ResponseNotReady()
  570.         self.msg is None
  571.         return self.msg.getheader(name, default)
  572.  
  573.     
  574.     def getheaders(self):
  575.         '''Return list of (header, value) tuples.'''
  576.         if self.msg is None:
  577.             raise ResponseNotReady()
  578.         self.msg is None
  579.         return self.msg.items()
  580.  
  581.  
  582.  
  583. class HTTPConnection:
  584.     _http_vsn = 11
  585.     _http_vsn_str = 'HTTP/1.1'
  586.     response_class = HTTPResponse
  587.     default_port = HTTP_PORT
  588.     auto_open = 1
  589.     debuglevel = 0
  590.     strict = 0
  591.     
  592.     def __init__(self, host, port = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT):
  593.         self.timeout = timeout
  594.         self.sock = None
  595.         self._buffer = []
  596.         self._HTTPConnection__response = None
  597.         self._HTTPConnection__state = _CS_IDLE
  598.         self._method = None
  599.         self._tunnel_host = None
  600.         self._tunnel_port = None
  601.         self._set_hostport(host, port)
  602.         if strict is not None:
  603.             self.strict = strict
  604.         
  605.  
  606.     
  607.     def _set_tunnel(self, host, port = None):
  608.         ''' Sets up the host and the port for the HTTP CONNECT Tunnelling.'''
  609.         self._tunnel_host = host
  610.         self._tunnel_port = port
  611.  
  612.     
  613.     def _set_hostport(self, host, port):
  614.         if port is None:
  615.             i = host.rfind(':')
  616.             j = host.rfind(']')
  617.             if i > j:
  618.                 
  619.                 try:
  620.                     port = int(host[i + 1:])
  621.                 except ValueError:
  622.                     raise InvalidURL("nonnumeric port: '%s'" % host[i + 1:])
  623.  
  624.                 host = host[:i]
  625.             else:
  626.                 port = self.default_port
  627.             if host and host[0] == '[' and host[-1] == ']':
  628.                 host = host[1:-1]
  629.             
  630.         
  631.         self.host = host
  632.         self.port = port
  633.  
  634.     
  635.     def set_debuglevel(self, level):
  636.         self.debuglevel = level
  637.  
  638.     
  639.     def _tunnel(self):
  640.         self._set_hostport(self._tunnel_host, self._tunnel_port)
  641.         self.send('CONNECT %s:%d HTTP/1.0\r\n\r\n' % (self.host, self.port))
  642.         response = self.response_class(self.sock, strict = self.strict, method = self._method)
  643.         (version, code, message) = response._read_status()
  644.         if code != 200:
  645.             self.close()
  646.             raise socket.error, 'Tunnel connection failed: %d %s' % (code, message.strip())
  647.         code != 200
  648.         while True:
  649.             line = response.fp.readline()
  650.             if line == '\r\n':
  651.                 break
  652.                 continue
  653.  
  654.     
  655.     def connect(self):
  656.         '''Connect to the host and port specified in __init__.'''
  657.         self.sock = socket.create_connection((self.host, self.port), self.timeout)
  658.         if self._tunnel_host:
  659.             self._tunnel()
  660.         
  661.  
  662.     
  663.     def close(self):
  664.         '''Close the connection to the HTTP server.'''
  665.         if self.sock:
  666.             self.sock.close()
  667.             self.sock = None
  668.         
  669.         if self._HTTPConnection__response:
  670.             self._HTTPConnection__response.close()
  671.             self._HTTPConnection__response = None
  672.         
  673.         self._HTTPConnection__state = _CS_IDLE
  674.  
  675.     
  676.     def send(self, str):
  677.         """Send `str' to the server."""
  678.         if self.sock is None:
  679.             if self.auto_open:
  680.                 self.connect()
  681.             else:
  682.                 raise NotConnected()
  683.         self.auto_open
  684.         if self.debuglevel > 0:
  685.             print 'send:', repr(str)
  686.         
  687.         
  688.         try:
  689.             blocksize = 8192
  690.             if hasattr(str, 'read') and not isinstance(str, array):
  691.                 if self.debuglevel > 0:
  692.                     print 'sendIng a read()able'
  693.                 
  694.                 data = str.read(blocksize)
  695.                 while data:
  696.                     self.sock.sendall(data)
  697.                     data = str.read(blocksize)
  698.             else:
  699.                 self.sock.sendall(str)
  700.         except socket.error:
  701.             v = None
  702.             if v[0] == 32:
  703.                 self.close()
  704.             
  705.             raise 
  706.  
  707.  
  708.     
  709.     def _output(self, s):
  710.         '''Add a line of output to the current request buffer.
  711.  
  712.         Assumes that the line does *not* end with \\r\\n.
  713.         '''
  714.         self._buffer.append(s)
  715.  
  716.     
  717.     def _send_output(self):
  718.         '''Send the currently buffered request and clear the buffer.
  719.  
  720.         Appends an extra \\r\\n to the buffer.
  721.         '''
  722.         self._buffer.extend(('', ''))
  723.         msg = '\r\n'.join(self._buffer)
  724.         del self._buffer[:]
  725.         self.send(msg)
  726.  
  727.     
  728.     def putrequest(self, method, url, skip_host = 0, skip_accept_encoding = 0):
  729.         """Send a request to the server.
  730.  
  731.         `method' specifies an HTTP request method, e.g. 'GET'.
  732.         `url' specifies the object being requested, e.g. '/index.html'.
  733.         `skip_host' if True does not add automatically a 'Host:' header
  734.         `skip_accept_encoding' if True does not add automatically an
  735.            'Accept-Encoding:' header
  736.         """
  737.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  738.             self._HTTPConnection__response = None
  739.         
  740.         if self._HTTPConnection__state == _CS_IDLE:
  741.             self._HTTPConnection__state = _CS_REQ_STARTED
  742.         else:
  743.             raise CannotSendRequest()
  744.         self._method = self._HTTPConnection__state == _CS_IDLE
  745.         if not url:
  746.             url = '/'
  747.         
  748.         str = '%s %s %s' % (method, url, self._http_vsn_str)
  749.         self._output(str)
  750.         if self._http_vsn == 11:
  751.             if not skip_host:
  752.                 netloc = ''
  753.                 if url.startswith('http'):
  754.                     (nil, netloc, nil, nil, nil) = urlsplit(url)
  755.                 
  756.                 if netloc:
  757.                     
  758.                     try:
  759.                         netloc_enc = netloc.encode('ascii')
  760.                     except UnicodeEncodeError:
  761.                         netloc_enc = netloc.encode('idna')
  762.  
  763.                     self.putheader('Host', netloc_enc)
  764.                 else:
  765.                     
  766.                     try:
  767.                         host_enc = self.host.encode('ascii')
  768.                     except UnicodeEncodeError:
  769.                         host_enc = self.host.encode('idna')
  770.  
  771.                     if self.port == self.default_port:
  772.                         self.putheader('Host', host_enc)
  773.                     else:
  774.                         self.putheader('Host', '%s:%s' % (host_enc, self.port))
  775.             
  776.             if not skip_accept_encoding:
  777.                 self.putheader('Accept-Encoding', 'identity')
  778.             
  779.         
  780.  
  781.     
  782.     def putheader(self, header, value):
  783.         """Send a request header line to the server.
  784.  
  785.         For example: h.putheader('Accept', 'text/html')
  786.         """
  787.         if self._HTTPConnection__state != _CS_REQ_STARTED:
  788.             raise CannotSendHeader()
  789.         self._HTTPConnection__state != _CS_REQ_STARTED
  790.         str = '%s: %s' % (header, value)
  791.         self._output(str)
  792.  
  793.     
  794.     def endheaders(self):
  795.         '''Indicate that the last header line has been sent to the server.'''
  796.         if self._HTTPConnection__state == _CS_REQ_STARTED:
  797.             self._HTTPConnection__state = _CS_REQ_SENT
  798.         else:
  799.             raise CannotSendHeader()
  800.         (self._HTTPConnection__state == _CS_REQ_STARTED)._send_output()
  801.  
  802.     
  803.     def request(self, method, url, body = None, headers = { }):
  804.         '''Send a complete request to the server.'''
  805.         
  806.         try:
  807.             self._send_request(method, url, body, headers)
  808.         except socket.error:
  809.             v = None
  810.             if v[0] != 32 or not (self.auto_open):
  811.                 raise 
  812.             not (self.auto_open)
  813.             self._send_request(method, url, body, headers)
  814.  
  815.  
  816.     
  817.     def _send_request(self, method, url, body, headers):
  818.         header_names = []([ k.lower() for k in headers ])
  819.         skips = { }
  820.         if 'accept-encoding' in header_names:
  821.             skips['skip_accept_encoding'] = 1
  822.         
  823.         self.putrequest(method, url, **skips)
  824.         if body and 'content-length' not in header_names:
  825.             thelen = None
  826.             
  827.             try:
  828.                 thelen = str(len(body))
  829.             except TypeError:
  830.                 te = None
  831.                 import os as os
  832.                 
  833.                 try:
  834.                     thelen = str(os.fstat(body.fileno()).st_size)
  835.                 except (AttributeError, OSError):
  836.                     if self.debuglevel > 0:
  837.                         print 'Cannot stat!!'
  838.                     
  839.                 except:
  840.                     self.debuglevel > 0
  841.                 
  842.  
  843.                 None<EXCEPTION MATCH>(AttributeError, OSError)
  844.  
  845.             if thelen is not None:
  846.                 self.putheader('Content-Length', thelen)
  847.             
  848.         
  849.         for hdr, value in headers.iteritems():
  850.             self.putheader(hdr, value)
  851.         
  852.         self.endheaders()
  853.         if body:
  854.             self.send(body)
  855.         
  856.  
  857.     
  858.     def getresponse(self):
  859.         '''Get the response from the server.'''
  860.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  861.             self._HTTPConnection__response = None
  862.         
  863.         if self._HTTPConnection__state != _CS_REQ_SENT or self._HTTPConnection__response:
  864.             raise ResponseNotReady()
  865.         self._HTTPConnection__response
  866.         if self.debuglevel > 0:
  867.             response = self.response_class(self.sock, self.debuglevel, strict = self.strict, method = self._method)
  868.         else:
  869.             response = self.response_class(self.sock, strict = self.strict, method = self._method)
  870.         response.begin()
  871.         if not response.will_close != _UNKNOWN:
  872.             raise AssertionError
  873.         self._HTTPConnection__state = _CS_IDLE
  874.         if response.will_close:
  875.             self.close()
  876.         else:
  877.             self._HTTPConnection__response = response
  878.         return response
  879.  
  880.  
  881.  
  882. class HTTP:
  883.     '''Compatibility class with httplib.py from 1.5.'''
  884.     _http_vsn = 10
  885.     _http_vsn_str = 'HTTP/1.0'
  886.     debuglevel = 0
  887.     _connection_class = HTTPConnection
  888.     
  889.     def __init__(self, host = '', port = None, strict = None):
  890.         '''Provide a default host, since the superclass requires one.'''
  891.         if port == 0:
  892.             port = None
  893.         
  894.         self._setup(self._connection_class(host, port, strict))
  895.  
  896.     
  897.     def _setup(self, conn):
  898.         self._conn = conn
  899.         self.send = conn.send
  900.         self.putrequest = conn.putrequest
  901.         self.endheaders = conn.endheaders
  902.         self.set_debuglevel = conn.set_debuglevel
  903.         conn._http_vsn = self._http_vsn
  904.         conn._http_vsn_str = self._http_vsn_str
  905.         self.file = None
  906.  
  907.     
  908.     def connect(self, host = None, port = None):
  909.         """Accept arguments to set the host/port, since the superclass doesn't."""
  910.         if host is not None:
  911.             self._conn._set_hostport(host, port)
  912.         
  913.         self._conn.connect()
  914.  
  915.     
  916.     def getfile(self):
  917.         """Provide a getfile, since the superclass' does not use this concept."""
  918.         return self.file
  919.  
  920.     
  921.     def putheader(self, header, *values):
  922.         '''The superclass allows only one value argument.'''
  923.         self._conn.putheader(header, '\r\n\t'.join(values))
  924.  
  925.     
  926.     def getreply(self):
  927.         '''Compat definition since superclass does not define it.
  928.  
  929.         Returns a tuple consisting of:
  930.         - server status code (e.g. \'200\' if all goes well)
  931.         - server "reason" corresponding to status code
  932.         - any RFC822 headers in the response from the server
  933.         '''
  934.         
  935.         try:
  936.             response = self._conn.getresponse()
  937.         except BadStatusLine:
  938.             e = None
  939.             self.file = self._conn.sock.makefile('rb', 0)
  940.             self.close()
  941.             self.headers = None
  942.             return (-1, e.line, None)
  943.  
  944.         self.headers = response.msg
  945.         self.file = response.fp
  946.         return (response.status, response.reason, response.msg)
  947.  
  948.     
  949.     def close(self):
  950.         self._conn.close()
  951.         self.file = None
  952.  
  953.  
  954.  
  955. try:
  956.     import ssl
  957. except ImportError:
  958.     warnings.catch_warnings().__exit__
  959.     warnings.catch_warnings().__exit__
  960.     warnings.catch_warnings()
  961. except:
  962.     warnings.catch_warnings().__exit__
  963.  
  964.  
  965. class HTTPSConnection(HTTPConnection):
  966.     '''This class allows communication via SSL.'''
  967.     default_port = HTTPS_PORT
  968.     
  969.     def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT):
  970.         HTTPConnection.__init__(self, host, port, strict, timeout)
  971.         self.key_file = key_file
  972.         self.cert_file = cert_file
  973.  
  974.     
  975.     def connect(self):
  976.         '''Connect to a host on a given (SSL) port.'''
  977.         sock = socket.create_connection((self.host, self.port), self.timeout)
  978.         if self._tunnel_host:
  979.             self.sock = sock
  980.             self._tunnel()
  981.         
  982.         self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
  983.  
  984.  
  985. __all__.append('HTTPSConnection')
  986.  
  987. class HTTPS(HTTP):
  988.     '''Compatibility with 1.5 httplib interface
  989.  
  990.         Python 1.5.2 did not have an HTTPS class, but it defined an
  991.         interface for sending http requests that is also useful for
  992.         https.
  993.         '''
  994.     _connection_class = HTTPSConnection
  995.     
  996.     def __init__(self, host = '', port = None, key_file = None, cert_file = None, strict = None):
  997.         if port == 0:
  998.             port = None
  999.         
  1000.         self._setup(self._connection_class(host, port, key_file, cert_file, strict))
  1001.         self.key_file = key_file
  1002.         self.cert_file = cert_file
  1003.  
  1004.  
  1005.  
  1006. def FakeSocket(sock, sslobj):
  1007.     warnings.warn("FakeSocket is deprecated, and won't be in 3.x.  " + 'Use the result of ssl.wrap_socket() directly instead.', DeprecationWarning, stacklevel = 2)
  1008.     return sslobj
  1009.  
  1010.  
  1011. class HTTPException(Exception):
  1012.     pass
  1013.  
  1014.  
  1015. class NotConnected(HTTPException):
  1016.     pass
  1017.  
  1018.  
  1019. class InvalidURL(HTTPException):
  1020.     pass
  1021.  
  1022.  
  1023. class UnknownProtocol(HTTPException):
  1024.     
  1025.     def __init__(self, version):
  1026.         self.args = (version,)
  1027.         self.version = version
  1028.  
  1029.  
  1030.  
  1031. class UnknownTransferEncoding(HTTPException):
  1032.     pass
  1033.  
  1034.  
  1035. class UnimplementedFileMode(HTTPException):
  1036.     pass
  1037.  
  1038.  
  1039. class IncompleteRead(HTTPException):
  1040.     
  1041.     def __init__(self, partial, expected = None):
  1042.         self.args = (partial,)
  1043.         self.partial = partial
  1044.         self.expected = expected
  1045.  
  1046.     
  1047.     def __repr__(self):
  1048.         if self.expected is not None:
  1049.             e = ', %i more expected' % self.expected
  1050.         else:
  1051.             e = ''
  1052.         return 'IncompleteRead(%i bytes read%s)' % (len(self.partial), e)
  1053.  
  1054.     
  1055.     def __str__(self):
  1056.         return repr(self)
  1057.  
  1058.  
  1059.  
  1060. class ImproperConnectionState(HTTPException):
  1061.     pass
  1062.  
  1063.  
  1064. class CannotSendRequest(ImproperConnectionState):
  1065.     pass
  1066.  
  1067.  
  1068. class CannotSendHeader(ImproperConnectionState):
  1069.     pass
  1070.  
  1071.  
  1072. class ResponseNotReady(ImproperConnectionState):
  1073.     pass
  1074.  
  1075.  
  1076. class BadStatusLine(HTTPException):
  1077.     
  1078.     def __init__(self, line):
  1079.         self.args = (line,)
  1080.         self.line = line
  1081.  
  1082.  
  1083. error = HTTPException
  1084.  
  1085. class LineAndFileWrapper:
  1086.     '''A limited file-like object for HTTP/0.9 responses.'''
  1087.     
  1088.     def __init__(self, line, file):
  1089.         self._line = line
  1090.         self._file = file
  1091.         self._line_consumed = 0
  1092.         self._line_offset = 0
  1093.         self._line_left = len(line)
  1094.  
  1095.     
  1096.     def __getattr__(self, attr):
  1097.         return getattr(self._file, attr)
  1098.  
  1099.     
  1100.     def _done(self):
  1101.         self._line_consumed = 1
  1102.         self.read = self._file.read
  1103.         self.readline = self._file.readline
  1104.         self.readlines = self._file.readlines
  1105.  
  1106.     
  1107.     def read(self, amt = None):
  1108.         if self._line_consumed:
  1109.             return self._file.read(amt)
  1110.         if not self._line_left:
  1111.             raise AssertionError
  1112.         if amt is None or amt > self._line_left:
  1113.             s = self._line[self._line_offset:]
  1114.             self._done()
  1115.             if amt is None:
  1116.                 return s + self._file.read()
  1117.             return s + self._file.read(amt - len(s))
  1118.         amt > self._line_left
  1119.         if not amt <= self._line_left:
  1120.             raise AssertionError
  1121.         i = self._line_offset
  1122.         j = i + amt
  1123.         s = self._line[i:j]
  1124.         self._line_offset = j
  1125.         self._line_left -= amt
  1126.         return s
  1127.  
  1128.     
  1129.     def readline(self):
  1130.         if self._line_consumed:
  1131.             return self._file.readline()
  1132.         if not self._line_left:
  1133.             raise AssertionError
  1134.         s = self._line[self._line_offset:]
  1135.         self._done()
  1136.         return s
  1137.  
  1138.     
  1139.     def readlines(self, size = None):
  1140.         if self._line_consumed:
  1141.             return self._file.readlines(size)
  1142.         if not self._line_left:
  1143.             raise AssertionError
  1144.         L = [
  1145.             self._line[self._line_offset:]]
  1146.         self._done()
  1147.         if size is None:
  1148.             return L + self._file.readlines()
  1149.         return L + self._file.readlines(size)
  1150.  
  1151.  
  1152.  
  1153. def test():
  1154.     '''Test this module.
  1155.  
  1156.     A hodge podge of tests collected here, because they have too many
  1157.     external dependencies for the regular test suite.
  1158.     '''
  1159.     import sys as sys
  1160.     import getopt as getopt
  1161.     (opts, args) = getopt.getopt(sys.argv[1:], 'd')
  1162.     dl = 0
  1163.     for o, a in opts:
  1164.         if o == '-d':
  1165.             dl = dl + 1
  1166.             continue
  1167.     
  1168.     host = 'www.python.org'
  1169.     selector = '/'
  1170.     if args[0:]:
  1171.         host = args[0]
  1172.     
  1173.     if args[1:]:
  1174.         selector = args[1]
  1175.     
  1176.     h = HTTP()
  1177.     h.set_debuglevel(dl)
  1178.     h.connect(host)
  1179.     h.putrequest('GET', selector)
  1180.     h.endheaders()
  1181.     (status, reason, headers) = h.getreply()
  1182.     print 'status =', status
  1183.     print 'reason =', reason
  1184.     print 'read', len(h.getfile().read())
  1185.     print 
  1186.     if headers:
  1187.         for header in headers.headers:
  1188.             print header.strip()
  1189.         
  1190.     
  1191.     print 
  1192.     
  1193.     class HTTP11(HTTP):
  1194.         _http_vsn = 11
  1195.         _http_vsn_str = 'HTTP/1.1'
  1196.  
  1197.     h = HTTP11('www.python.org')
  1198.     h.putrequest('GET', 'http://www.python.org/~jeremy/')
  1199.     h.endheaders()
  1200.     h.getreply()
  1201.     h.close()
  1202.     
  1203.     try:
  1204.         import ssl
  1205.     except ImportError:
  1206.         pass
  1207.  
  1208.     for host, selector in (('sourceforge.net', '/projects/python'),):
  1209.         print 'https://%s%s' % (host, selector)
  1210.         hs = HTTPS()
  1211.         hs.set_debuglevel(dl)
  1212.         hs.connect(host)
  1213.         hs.putrequest('GET', selector)
  1214.         hs.endheaders()
  1215.         (status, reason, headers) = hs.getreply()
  1216.         print 'status =', status
  1217.         print 'reason =', reason
  1218.         print 'read', len(hs.getfile().read())
  1219.         print 
  1220.         if headers:
  1221.             for header in headers.headers:
  1222.                 print header.strip()
  1223.             
  1224.         
  1225.         print 
  1226.     
  1227.  
  1228.